<template>
  <div class="common-layout">
    <el-container>
      <el-header style="height: auto;">
        <el-card>
          <el-form :inline="true" :model="formInline" class="demo-form-inline">
            <el-form-item label="托盘名称">
              <el-input 
                v-model="formInline.trayName" 
                placeholder="请输入托盘名称" 
                clearable 
                style="width: 200px;" 
              />
            </el-form-item>
            <el-form-item label="类型">
              <el-select
                v-model="formInline.barcodeId"
                placeholder="请选择"
                clearable
                style="width: 200px;"
              >
                <el-option 
                  :label="item.dictionaryName" 
                  :value="item.dictionaryId" 
                  v-for="item in typeOptions" 
                  :key="item.dictionaryId"
                />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" size="small" @click="handleQuery">查询</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </el-header>
      <el-main>
        <el-card style="height: auto;">
          <div style="margin-bottom: 10px;">
            <el-button type="primary" size="small" @click="handleAdd">添加</el-button>
            <el-button type="primary" size="small" @click="openBatchDialog">批量生成</el-button>
            <el-button type="success" size="small" @click="handleGenerateBarcode">生成条码</el-button>
            <el-button type="success" size="small" @click="handlePrintBarcode">打印条码</el-button>
          </div>
          <el-table
            ref="multipleTableRef"
            :data="tableData"
            row-key="trayId"
            style="width: 100%"
            @selection-change="handleSelectionChange"
            border
          >
            <el-table-column type="selection" width="55" />
            <el-table-column type="index" label="序号" width="90" />
            <el-table-column prop="barCode" label="托盘条码" width="150" />
            <el-table-column prop="trayName" label="托盘名称" width="180" />
            <el-table-column prop="trayState" label="状态" width="120">
              <template #default="scope">
                <el-tag type="success" v-if="scope.row.trayState === 1">启用</el-tag>
                <el-tag type="danger" v-if="scope.row.trayState === 2">禁用</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="createrTime" label="创建时间" width="150">
              <template #default="scope">
                {{ formatDate(scope.row.createrTime) }}
              </template>
            </el-table-column>
            <el-table-column prop="updateTime" label="修改时间" width="150">
              <template #default="scope">
                {{ formatDate(scope.row.updateTime) }}
              </template>
            </el-table-column>
            <el-table-column label="操作" width="150" fixed="right">
              <template #default="scope">
                <el-button link type="primary" size="small" @click="handleEdit(scope.row)">
                  编辑
                </el-button>
                <el-button link type="danger" size="small" @click="handleDelete(scope.row)">
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
        <el-card style="margin-top: 20px;">
          <div style="display: flex; justify-content: space-between; align-items: center;">
            <div>共{{ page.listCount }}条</div>
            <el-pagination
              v-model:current-page="page.pageindex"
              v-model:page-size="page.pagesize"
              :page-sizes="[10, 20, 50, 100]"
              :background="true"
              layout="prev, pager, next"
              :total="page.listCount"
              @current-change="handleCurrentChange"
            />
            <div style="display: flex; align-items: center; gap: 10px;">
              <el-select v-model="page.pagesize" @change="handleSizeChange" style="width: 120px;">
                <el-option label="10条/页" :value="10" />
                <el-option label="20条/页" :value="20" />
                <el-option label="50条/页" :value="50" />
                <el-option label="100条/页" :value="100" />
              </el-select>
              <div style="display: flex; align-items: center; gap: 5px;">
                <span>前往</span>
                <el-input 
                  v-model="jumpPage" 
                  style="width: 60px;" 
                  @keyup.enter="handleJumpPage"
                />
                <span>页</span>
              </div>
            </div>
          </div>
        </el-card>
      </el-main>
    </el-container>

    <!-- 添加/编辑托盘弹框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="isEdit ? '编辑托盘' : '添加托盘'"
      width="500px"
      @close="handleDialogClose"
    >
      <el-form
        ref="trayFormRef"
        :model="trayForm"
        :rules="trayFormRules"
        label-width="100px"
      >
        <el-form-item label="托盘条码" prop="barCode" required>
          <el-input
            v-model="trayForm.barCode"
            placeholder="请输入托盘条码"
            clearable
          />
        </el-form-item>
        <el-form-item label="条码类型" prop="barcodeId" required>
          <el-select
            v-model="trayForm.barcodeId"
            placeholder="请选择条码类型"
            clearable
            style="width: 100%;"
          >
            <el-option
              :label="item.dictionaryName"
              :value="item.dictionaryId"
              v-for="item in typeOptions"
              :key="item.dictionaryId"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="托盘名称" prop="trayName" required>
          <el-input
            v-model="trayForm.trayName"
            placeholder="请输入托盘名称"
            clearable
          />
        </el-form-item>
        <el-form-item label="状态" prop="trayState" required>
          <el-radio-group v-model="trayForm.trayState">
            <el-radio :value="1">启用</el-radio>
            <el-radio :value="2">停用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSaveTray">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 条码预览弹框 -->
    <el-dialog
      v-model="printDialogVisible"
      title="条码预览"
      width="800px"
      destroy-on-close
    >
      <div v-if="generatedBarcodes.length" class="barcode-preview">
        <div class="barcode-card" v-for="item in generatedBarcodes" :key="item.trayId">
          <div class="barcode-title">{{ item.trayName || '--' }}</div>
          <img :src="item.dataUrl" alt="barcode" />
          <div class="barcode-code">{{ item.barCode }}</div>
        </div>
      </div>
      <el-empty v-else description="请先点击生成条码" />
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="printDialogVisible = false">关闭</el-button>
          <el-button type="primary" @click="handleConfirmPrint">打印</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 批量新增弹框 -->
    <el-dialog
      v-model="batchDialogVisible"
      title="批量添加"
      width="520px"
      @close="handleBatchDialogClose"
    >
      <el-form
        ref="batchFormRef"
        :model="batchForm"
        :rules="batchFormRules"
        label-width="100px"
      >
        <el-form-item label="起始条码" prop="startBarCode" required>
          <el-input v-model="batchForm.startBarCode" placeholder="请输入起始条码" clearable />
        </el-form-item>
        <el-form-item label="生成数量" prop="quantity" required>
          <el-input
            v-model="batchForm.quantity"
            placeholder="请输入生成数量"
            type="number"
            min="1"
            clearable
          />
        </el-form-item>
        <el-form-item label="条码类型" prop="barcodeId" required>
          <el-select
            v-model="batchForm.barcodeId"
            placeholder="请选择条码类型"
            style="width: 100%;"
            clearable
          >
            <el-option
              v-for="item in typeOptions"
              :key="item.dictionaryId"
              :label="item.dictionaryName"
              :value="item.dictionaryId"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="是否打印" prop="autoPrint">
          <el-radio-group v-model="batchForm.autoPrint">
            <el-radio :value="false">不打印</el-radio>
            <el-radio :value="true">打印</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="batchDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleBatchConfirm">确定生成</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, reactive, ref, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox, type TableInstance, type FormInstance, type FormRules } from 'element-plus'
import myaxios from '@/http/MyAxios'
import moment from 'moment'
import router from '@/router'
import JsBarcode from 'jsbarcode'

interface BarcodePreview {
  trayId: number
  trayName: string
  barCode: string
  dataUrl: string
}
// 查询条件
const formInline = reactive({
  trayName: '',
  barcodeId: '',
})

// 分页条件
const page = reactive({
  pageindex: 1,
  pagesize: 10,
  listCount: 0,
  pageCount: 0,
})

// 跳转页码
const jumpPage = ref(1)

// 表格数据
const tableData = ref([])

// 选中的数据
const multipleTableRef = ref<TableInstance>()
const multipleSelection = ref([])

// 类型选项（字典数据）
const typeOptions = ref<any[]>([])

// 条码类型父级字典ID
const barcodeTypeParentId = ref<number | null>(null)

// 弹框相关
const dialogVisible = ref(false)
const isEdit = ref(false)
const currentTrayId = ref<number | null>(null)
const trayFormRef = ref<FormInstance>()
const trayForm = reactive({
  barCode: '',
  barcodeId: null as number | null,
  trayName: '',
  trayState: 1,
})

const generatedBarcodes = ref<BarcodePreview[]>([])
const printDialogVisible = ref(false)
const batchDialogVisible = ref(false)
const batchFormRef = ref<FormInstance>()
const batchForm = reactive({
  startBarCode: '',
  quantity: 1 as number | string,
  barcodeId: null as number | null,
  autoPrint: false,
})
const batchFormRules = reactive<FormRules>({
  startBarCode: [{ required: true, message: '请输入起始条码', trigger: 'blur' }],
  quantity: [
    { required: true, message: '请输入生成数量', trigger: 'blur' },
    {
      validator: (_rule, value, callback) => {
        const num = Number(value)
        if (Number.isNaN(num) || num <= 0) {
          callback(new Error('数量必须为正整数'))
          return
        }
        if (num > 500) {
          callback(new Error('单次最多生成 500 条'))
          return
        }
        callback()
      },
      trigger: 'blur',
    },
  ],
  barcodeId: [{ required: true, message: '请选择条码类型', trigger: 'change' }],
})

// 表单验证规则
const trayFormRules = reactive<FormRules>({
  barCode: [
    { required: true, message: '请输入托盘条码', trigger: 'blur' },
  ],
  barcodeId: [
    { required: true, message: '请选择条码类型', trigger: 'change' },
  ],
  trayName: [
    { required: true, message: '请输入托盘名称', trigger: 'blur' },
  ],
  trayState: [
    { required: true, message: '请选择状态', trigger: 'change' },
  ],
})

// 格式化日期
const formatDate = (date: any) => {
  if (!date) return '--'
  try {
    return moment(date).format('YYYY-MM-DD')
  } catch {
    return '--'
  }
}

// 获取条码类型父级字典ID
const getBarcodeTypeParentId = async () => {
  try {
    const res = await myaxios.get('/api/Dictionary/GetParentDictionaryList', {
      params: {
        pageindex: 1,
        pagesize: 999,
        dictionaryName: '条码类型',
      },
    })
    if (res.data.code === 200 && res.data.data?.data) {
      const parentDict = res.data.data.data.find(
        (item: any) => item.dictionaryName === '条码类型'
      )
      if (parentDict) {
        barcodeTypeParentId.value = parentDict.dictionaryId
        // 获取子级字典（类型选项）
        await getTypeOptions(parentDict.dictionaryId)
      }
    }
  } catch (error) {
    console.error('获取条码类型父级字典失败:', error)
    ElMessage.error('获取条码类型字典失败')
  }
}

// 获取类型选项（子级字典）
const getTypeOptions = async (parentId: number) => {
  try {
    const res = await myaxios.get('/api/Dictionary/GetChildDictionaryList', {
      params: {
        parentId: parentId,
        pageindex: 1,
        pagesize: 999,
      },
    })
    if (res.data.code === 200 && res.data.data?.data) {
      typeOptions.value = res.data.data.data
    }
  } catch (error) {
    console.error('获取类型选项失败:', error)
  }
}

// 查询托盘列表
const handleQuery = () => {
  page.pageindex = 1
  fetchTrayList()
}

// 获取托盘列表
const fetchTrayList = async () => {
  try {
    const params: any = {
      pageindex: page.pageindex,
      pagesize: page.pagesize,
    }
    if (formInline.trayName) {
      params.trayName = formInline.trayName
    }
    if (formInline.barcodeId) {
      params.barcodeId = formInline.barcodeId
    }

    const res = await myaxios.get('/api/Tray/GetTrayList', { params })
    if (res.data.code === 200 && res.data.data) {
      tableData.value = res.data.data.data || []
      page.listCount = res.data.data.listCount || 0
      page.pageCount = res.data.data.pageCount || 0
    } else {
      ElMessage.error(res.data.message || '获取托盘列表失败')
    }
  } catch (error) {
    console.error('获取托盘列表失败:', error)
    ElMessage.error('获取托盘列表失败，请稍后重试')
  }
}

// 分页大小改变
const handleSizeChange = () => {
  page.pageindex = 1
  fetchTrayList()
}

// 当前页改变
const handleCurrentChange = () => {
  fetchTrayList()
}

// 跳转页码
const handleJumpPage = () => {
  const targetPage = Number(jumpPage.value)
  if (targetPage >= 1 && targetPage <= page.pageCount) {
    page.pageindex = targetPage
    fetchTrayList()
  } else {
    ElMessage.warning(`请输入1-${page.pageCount}之间的页码`)
  }
}

// 选择变化
const handleSelectionChange = (val: any) => {
  multipleSelection.value = val
}

// 添加
const handleAdd = () => {
  isEdit.value = false
  currentTrayId.value = null
  dialogVisible.value = true
  // 重置表单
  trayForm.barCode = ''
  trayForm.barcodeId = null
  trayForm.trayName = ''
  trayForm.trayState = 1
  // 清除验证
  nextTick(() => {
    trayFormRef.value?.clearValidate()
  })
}

// 关闭弹框
const handleDialogClose = () => {
  trayFormRef.value?.resetFields()
}

// 保存托盘
const handleSaveTray = async () => {
  if (!trayFormRef.value) return

  await trayFormRef.value.validate(async (valid) => {
    if (!valid) return

    try {
      let res
      if (isEdit.value && currentTrayId.value) {
        // 编辑模式
        res = await myaxios.put('/api/Tray/UpdateTray', {
          trayId: currentTrayId.value,
          barCode: trayForm.barCode,
          barcodeId: trayForm.barcodeId,
          trayName: trayForm.trayName,
          trayState: trayForm.trayState,
        })
      } else {
        // 添加模式
        res = await myaxios.post('/api/Tray/CreateTray', {
          barCode: trayForm.barCode,
          barcodeId: trayForm.barcodeId,
          trayName: trayForm.trayName,
          trayState: trayForm.trayState,
        })
      }

      if (res.data.code === 200) {
        ElMessage.success(res.data.message || (isEdit.value ? '更新托盘成功' : '添加托盘成功'))
        dialogVisible.value = false
        // 刷新列表
        fetchTrayList()
      } else {
        ElMessage.error(res.data.message || (isEdit.value ? '更新托盘失败' : '添加托盘失败'))
      }
    } catch (error: any) {
      console.error(isEdit.value ? '更新托盘失败:' : '添加托盘失败:', error)
      ElMessage.error(error?.response?.data?.message || (isEdit.value ? '更新托盘失败，请稍后重试' : '添加托盘失败，请稍后重试'))
    }
  })
}

const loadNextTrayCode = async () => {
  try {
    const res = await myaxios.get('/api/Tray/GetNextTrayBarcode')
    if (res.data.code === 200 && res.data.data) {
      batchForm.startBarCode = res.data.data
    }
  } catch (error) {
    console.error('获取起始条码失败', error)
  }
}

const openBatchDialog = async () => {
  batchDialogVisible.value = true
  batchForm.quantity = 1
  batchForm.autoPrint = false
  batchForm.barcodeId = null
  await nextTick()
  batchFormRef.value?.clearValidate()
  await loadNextTrayCode()
}

const handleBatchDialogClose = () => {
  batchFormRef.value?.resetFields()
}

const createBarcodeImage = (code: string) => {
  const canvas = document.createElement('canvas')
  JsBarcode(canvas, code, {
    format: 'CODE128',
    displayValue: true,
    fontSize: 16,
    textMargin: 8,
    width: 2,
    height: 80,
    margin: 10,
  })
  return canvas.toDataURL('image/png')
}

const handleGenerateBarcode = () => {
  if (multipleSelection.value.length === 0) {
    ElMessage.warning('请至少选择一条数据')
    return
  }

  const invalid = multipleSelection.value.filter((item: any) => !item.barCode)
  if (invalid.length > 0) {
    ElMessage.warning('所选托盘存在空条码，请先编辑并保存条码')
    return
  }

  generatedBarcodes.value = multipleSelection.value.map((item: any) => ({
    trayId: item.trayId,
    trayName: item.trayName,
    barCode: item.barCode,
    dataUrl: createBarcodeImage(item.barCode),
  }))

  printDialogVisible.value = true
  ElMessage.success(`成功生成 ${generatedBarcodes.value.length} 个条形码`)
}

const chunkBarcodes = (source: BarcodePreview[], size: number) => {
  const result: BarcodePreview[][] = []
  for (let i = 0; i < source.length; i += size) {
    result.push(source.slice(i, i + size))
  }
  return result
}

const buildPrintHtml = (items: BarcodePreview[]) => {
  const timestamp = moment().format('YYYY/MM/DD HH:mm')
  const chunks = chunkBarcodes(items, 6) // 每页显示 6 个条码（3 行 * 2 列）
  const pages = chunks
    .map((chunk, pageIndex) => {
      const cards = chunk
        .map(
          (item) => `
            <div class="print-card">
              <div class="print-card__title">${item.trayName || '托盘'}</div>
              <div class="print-card__barcode">
                <img src="${item.dataUrl}" alt="${item.barCode}" />
              </div>
              <div class="print-card__code">${item.barCode}</div>
              <div class="print-card__meta">批次：${moment().format('YYYYMMDD')}</div>
            </div>
          `,
        )
        .join('')

      return `
        <div class="print-page">
          <div class="print-header">
            <div class="header-left">
              <div class="brand">WMS 托盘条码</div>
              <div class="sub">打印时间：${timestamp}</div>
            </div>
            <div class="header-right">第 ${pageIndex + 1} / ${chunks.length} 页</div>
          </div>
          <div class="print-grid">
            ${cards}
          </div>
          <div class="print-footer">
            <span>制表人：__________</span>
            <span>仓库：________________________</span>
          </div>
        </div>
        ${pageIndex < chunks.length - 1 ? '<div class="page-break"></div>' : ''}
      `
    })
    .join('')

  return `<!DOCTYPE html>
  <html lang="zh-cn">
    <head>
      <meta charset="utf-8" />
      <title>托盘条码</title>
      <style>
        body { font-family: 'Microsoft YaHei', Arial, sans-serif; margin: 0; padding: 0; background-color: #f6f7fb; }
        .print-page { width: 100%; min-height: 100vh; padding: 30px 50px; box-sizing: border-box; background-color: #fff; }
        .print-header { display: flex; justify-content: space-between; align-items: baseline; border-bottom: 1px solid #ccc; padding-bottom: 12px; }
        .brand { font-size: 20px; font-weight: 600; }
        .sub { font-size: 13px; color: #666; margin-top: 4px; }
        .header-right { font-size: 13px; color: #888; }
        .print-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 28px; margin-top: 32px; }
        .print-card { border: 1px solid #dcdfe6; border-radius: 10px; padding: 18px 12px 14px; text-align: center; box-shadow: 0 3px 8px rgba(0,0,0,0.05); }
        .print-card__title { font-size: 15px; font-weight: 500; margin-bottom: 12px; }
        .print-card__barcode img { width: 220px; height: auto; }
        .print-card__code { margin-top: 12px; font-size: 18px; letter-spacing: 4px; }
        .print-card__meta { margin-top: 6px; font-size: 12px; color: #888; }
        .print-footer { margin-top: 40px; display: flex; justify-content: space-between; font-size: 13px; color: #666; border-top: 1px solid #dcdfe6; padding-top: 10px; }
        .page-break { page-break-after: always; }
        @media print {
          .print-page { min-height: auto; height: 100vh; }
          body { background: #fff; }
          .print-card { box-shadow: none; }
        }
      </style>
    </head>
    <body>
      ${pages}
    </body>
  </html>`
}

const handlePrintBarcode = () => {
  if (!generatedBarcodes.value.length) {
    if (multipleSelection.value.length === 0) {
      ElMessage.warning('请先选择托盘')
    } else {
      ElMessage.warning('请先点击“生成条码”')
    }
    return
  }
  printDialogVisible.value = true
}

const handleConfirmPrint = () => {
  if (!generatedBarcodes.value.length) {
    ElMessage.warning('请先生成条码')
    return
  }
  const win = window.open('', '_blank', 'width=900,height=600')
  if (!win) {
    ElMessage.error('浏览器阻止了弹窗，请允许后重试')
    return
  }
  win.document.write(buildPrintHtml(generatedBarcodes.value))
  win.document.close()
}

const handleBatchConfirm = () => {
  if (!batchFormRef.value) return
  batchFormRef.value.validate(async (valid) => {
    if (!valid) return
    try {
      const payload = {
        startBarCode: batchForm.startBarCode?.trim(),
        quantity: Number(batchForm.quantity),
        barcodeId: batchForm.barcodeId,
      }
      const res = await myaxios.post('/api/Tray/BatchCreateTrays', payload)
      if (res.data.code === 200 && Array.isArray(res.data.data)) {
        ElMessage.success(`成功生成 ${res.data.data.length} 条托盘`)
        batchDialogVisible.value = false
        await fetchTrayList()
        if (batchForm.autoPrint && res.data.data.length > 0) {
          generatedBarcodes.value = res.data.data.map((item: any) => ({
            trayId: item.trayId,
            trayName: item.trayName,
            barCode: item.barCode,
            dataUrl: createBarcodeImage(item.barCode),
          }))
          printDialogVisible.value = true
        }
      } else {
        ElMessage.error(res.data.message || '批量生成失败')
      }
    } catch (error) {
      console.error('批量生成失败', error)
      ElMessage.error('批量生成失败，请稍后重试')
    }
  })
}

// 编辑
const handleEdit = (row: any) => {
  isEdit.value = true
  currentTrayId.value = row.trayId
  dialogVisible.value = true
  // 填充表单数据
  trayForm.barCode = row.barCode || ''
  trayForm.barcodeId = row.barcodeId || null
  trayForm.trayName = row.trayName || ''
  trayForm.trayState = row.trayState || 1
  // 清除验证
  nextTick(() => {
    trayFormRef.value?.clearValidate()
  })
}

// 删除
const handleDelete = (row: any) => {
  ElMessageBox.confirm('确认删除该托盘吗?', '警告', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(() => {
      myaxios
        .put(`/api/Tray/DeleteTray?trayId=${row.trayId}`)
        .then((res) => {
          if (res.data.code === 200) {
            ElMessage.success(res.data.message)
            fetchTrayList()
          } else {
            ElMessage.error(res.data.message)
          }
        })
        .catch((error) => {
          console.error('删除托盘失败:', error)
          ElMessage.error('删除托盘失败')
        })
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消删除',
      })
    })
}

// 监听分页变化
watch(
  () => page.pageindex,
  (newVal) => {
    jumpPage.value = newVal
  }
)

// 初始化
onMounted(() => {
  getBarcodeTypeParentId()
  fetchTrayList()
  jumpPage.value = 1
})
</script>

<style>
.demo-form-inline .el-input {
  --el-input-width: 220px;
}

.demo-form-inline .el-select {
  --el-select-width: 220px;
}

.barcode-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  justify-content: center;
}

.barcode-card {
  text-align: center;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  padding: 12px 16px;
  background-color: #fff;
  width: 260px;
}

.barcode-card img {
  width: 220px;
  height: auto;
  margin: 0 auto;
}

.barcode-title {
  margin-bottom: 8px;
  font-size: 14px;
}

.barcode-code {
  margin-top: 8px;
  font-size: 16px;
  letter-spacing: 2px;
}

</style>

